﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using AMVInfoSpace;

namespace AMVCommander
{
    public partial class FormEditAmv : Form
    {
        bool bOk = false;
        public AMV resultAmv;
        AMV editAmv;
        FormEditMusic frmEditMsc = new FormEditMusic();
        FormEditItem frmEditItem = new FormEditItem();
        bool tryAutoAttachToAMVNews = false;

        public FormEditAmv()
        {
            InitializeComponent();
            Width = Gl.frmEditAmv_bOpenFind ? 1488 : 576;
            if (Gl.frmEditAmv_Pos.X != -1)
            {
                StartPosition = FormStartPosition.Manual;
                Location = Gl.frmEditAmv_Pos;
            }
        }

        /// <summary>Диалог редактирования AMV</summary>
        /// <param name="EditAmv">Редактируемое AMV</param>
        /// <param name="TryAutoAttachToAMVNews">Попытаться автоматически привязать к сайту AMVNews</param>
        public bool ShowDialog(AMV EditAmv, bool TryAutoAttachToAMVNews)
        {
            bOk = false;
            editAmv = EditAmv;
            tryAutoAttachToAMVNews = TryAutoAttachToAMVNews;
            resultAmv = editAmv.Clone();

            txbName.Text = resultAmv.Name;
            txbFPath.Text = resultAmv.FLocalPath;
            txbComment.Text = resultAmv.Comment;
            ReFillMusic();
            ReFillAuthors();
            ReFillAwards();
            ReFillAnime();
            ReFillTags();

            FillSitesInfo();

            txbMD5Len.Text = EditAmv.MD5Len;

            if (Gl.infoL.Count == 0)
            {
                Gl.LoadAmvInfoList();
                FillBindData();
            }

            FillFindData(ESpace.Comm.GetFileName(Gl.Sett.DPathHomeDir + "\\" + editAmv.FLocalPath));
            FillCashList();
            ReFillAmvInfoList();

            ShowDialog();
            return bOk;
        }

        private void FormEditAmv_Shown(object sender, EventArgs e)
        {
            if (tryAutoAttachToAMVNews)
            {
                FormTryParseHtmlAMV frm = new FormTryParseHtmlAMV();
                AMVInfo info = null;
                if (frm.ShowDialog(resultAmv.GetAMVNewsIdByFileName(), out info))
                {
                    MessageBox.Show("Данные успешно загружены с сайта AMVNews\r\nПроверьте корректность данных и отредактируйте при необходимости");
                    FillAmvInfoData(info, true);
                }
                frm.Dispose();
            }
        }

        #region *** ReFill ************************************

        void ReFillMusic()
        {
            List<string> strL = new List<string>();
            for (int i = 0; i < resultAmv.Msc.Count; i++)
            {
                strL.Add(resultAmv.Msc[i].Author + " - " + resultAmv.Msc[i].Name);
            }
            lbMsc.Refill(strL.ToArray());
        }
        void ReFillTags()
        {
            List<string> strL = new List<string>();
            for (int i = 0; i < resultAmv.Tags.Count; i++)
            {
                strL.Add(resultAmv.Tags[i]);
            }
            lbTag.Refill(strL.ToArray());
        }
        void ReFillAnime()
        {
            List<string> strL = new List<string>();
            for (int i = 0; i < resultAmv.Anm.Count; i++)
            {
                strL.Add(resultAmv.Anm[i]);
            }
            lbAnm.Refill(strL.ToArray());
        }
        void ReFillAuthors()
        {
            List<string> strL = new List<string>();
            for (int i = 0; i < resultAmv.Atr.Count; i++)
            {
                strL.Add(resultAmv.Atr[i]);
            }
            lbAtr.Refill(strL.ToArray());
        }
        void ReFillAwards()
        {
            List<string> strL = new List<string>();
            for (int i = 0; i < resultAmv.Awd.Count; i++)
            {
                strL.Add(resultAmv.Awd[i]);
            }
            lbAwd.Refill(strL.ToArray());
        }

        #endregion *** ReFill ************************************

        private void btnOk_Click(object sender, EventArgs e)
        {
            // проверка на уникальность имени amv
            String amvName = txbName.Text.Trim();
            String localPath = txbFPath.Text.Trim();
            if (amvName == "") { MessageBox.Show("Не указано название AMV"); return; }
            if (Gl.DB.IndexOfName(amvName) != -1 && (editAmv == null || editAmv.Name.ToUpper() != amvName.ToUpper())) { MessageBox.Show("AMV с таким названием уже существует"); return; }

            // проверка уникальности md5
            if (editAmv == null && Gl.DB.IndexOfMD5(resultAmv.MD5Len) != -1) { MessageBox.Show("Такой файл уже существует в базе. Вы пытаетесь добавить дубликат"); return; }

            #region *** привязки к сайтам ***

            if (!SetSiteLink(SITE.AMVNews, txbAmvNewsNum, txbAmvNewsRating, txbAmvNewsRatingDate)) return;
            if (!SetSiteLink(SITE.Akross, txbAkrossNum, txbAkrossRating, txbAkrossRatingDate)) return;
            if (!SetSiteLink(SITE.CreaCon, txbCreaConNum, txbCreaConRating, txbCreaConRatingDate)) return;

            #endregion *** привязки к сайтам ***

            resultAmv.Name = amvName;
            resultAmv.FLocalPath = localPath;
            resultAmv.Comment = txbComment.Text;
            bOk = true;
            Close();
        }

        /// <summary>Установка привязки к сайту с полей редактирования
        /// Возвращает, все ли данные введены корректно</summary>
        bool SetSiteLink(SITE Site, TextBox TxbSiteNum, TextBox TxbRating, TextBox TxbRatingDate)
        {
            int SiteNum = -1;
            if (TxbSiteNum.Text.Trim() != "")
            {
                int.TryParse(TxbSiteNum.Text.Trim(), out SiteNum);
                if (SiteNum < 1) { MessageBox.Show("Неверно указано AMVNews #"); return false; }
            }

            if (SiteNum != -1)
            {
                decimal rating; if (!decimal.TryParse(TxbRating.Text.Replace('.', ','), out rating)) rating = 0;
                DateTime ratingDate; if (!DateTime.TryParse(TxbRatingDate.Text, out ratingDate)) ratingDate = DateTime.MinValue;

                if (!resultAmv.Sites.ContainsKey(Site))
                    resultAmv.Sites.Add(Site, new AMVSite(SiteNum, rating, rating == 0 ? DateTime.MinValue : ratingDate));
                resultAmv.Sites[Site].ID = SiteNum;
                resultAmv.Sites[Site].Rating = rating;
                resultAmv.Sites[Site].LastUpdateRating = rating == 0 ? DateTime.MinValue : ratingDate;
            }
            else if (resultAmv.Sites.ContainsKey(Site)) resultAmv.Sites.Remove(Site);
            return true;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        #region *** события кнопок меню ************************************

        private void mBtnTagAdd_Click(object sender, EventArgs e)
        {
            if (frmEditItem.ShowDialog("", resultAmv.Tags.ToArray(), Gl.DB.GetAllTags().ToArray(), "Добавление тега"))
            {
                resultAmv.Tags.Add((string)frmEditItem.Value);
                lbTag.Add((string)frmEditItem.Value);
                lbTag.SelectedIndex = lbTag.Count - 1;
            }
        }

        private void mBtnTagEdit_Click(object sender, EventArgs e)
        {
            List<String> ex = new List<string>(resultAmv.Tags);
            if (frmEditItem.ShowDialog(resultAmv.Tags[lbTag.SelectedIndex], ex.ToArray(), Gl.DB.GetAllTags().ToArray(), "Редактирование тега"))
            {
                resultAmv.Tags[lbTag.SelectedIndex] = (string)frmEditItem.Value;
                ReFillTags();
            }
        }

        private void mBtnTagDel_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Действительно удалить запись?", "Удаление записи", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                resultAmv.Tags.RemoveAt(lbTag.SelectedIndex);
                ReFillTags();
            }
        }

        private void mBtnMscAdd_Click(object sender, EventArgs e)
        {
            if (frmEditMsc.ShowDialogAdd("", "", resultAmv.Msc.ToArray()))
            {
                resultAmv.Msc.Add(frmEditMsc.val);
                ReFillMusic();
            }
        }

        private void mBtnMscEdit_Click(object sender, EventArgs e)
        {
            if (frmEditMsc.ShowDialogEdit(resultAmv.Msc[lbMsc.SelectedIndex], resultAmv.Msc.ToArray()))
            {
                resultAmv.Msc[lbMsc.SelectedIndex].Name = frmEditMsc.val.Name;
                resultAmv.Msc[lbMsc.SelectedIndex].Author = frmEditMsc.val.Author;
                ReFillMusic();
            }
        }

        private void mBtnMscDel_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Действительно удалить запись?", "Удаление записи", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                resultAmv.Msc.RemoveAt(lbMsc.SelectedIndex);
                ReFillMusic();
            }
        }

        private void mBtnAtrAdd_Click(object sender, EventArgs e)
        {
            if (frmEditItem.ShowDialog("", resultAmv.Atr.ToArray(), Gl.DB.GetAllAutors().ToArray(), "Добавление автора"))
            {
                resultAmv.Atr.Add((string)frmEditItem.Value);
                lbAtr.Add((string)frmEditItem.Value);
                lbAtr.SelectedIndex = lbAtr.Count - 1;
            }
        }

        private void mBtnAtrEdit_Click(object sender, EventArgs e)
        {
            List<String> ex = new List<string>(resultAmv.Atr);
            if (frmEditItem.ShowDialog(resultAmv.Atr[lbAtr.SelectedIndex], ex.ToArray(), Gl.DB.GetAllAutors().ToArray(), "Редактирование автора"))
            {
                resultAmv.Atr[lbAtr.SelectedIndex] = (string)frmEditItem.Value;
                ReFillAuthors();
            }
        }

        private void mBtnAtrDel_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Действительно удалить запись?", "Удаление записи", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                resultAmv.Atr.RemoveAt(lbAtr.SelectedIndex);
                ReFillAuthors();
            }
        }

        private void mBtnAnmAdd_Click(object sender, EventArgs e)
        {
            if (frmEditItem.ShowDialog("", resultAmv.Anm.ToArray(), Gl.DB.GetAllAnime().ToArray(), "Добавление аниме"))
            {
                resultAmv.Anm.Add((string)frmEditItem.Value);
                lbAnm.Add((string)frmEditItem.Value);
                lbAnm.SelectedIndex = lbAnm.Count - 1;
            }
        }

        private void mBtnAnmEdit_Click(object sender, EventArgs e)
        {
            List<String> ex = new List<string>(resultAmv.Anm);
            if (frmEditItem.ShowDialog(resultAmv.Anm[lbAnm.SelectedIndex], ex.ToArray(), Gl.DB.GetAllAnime().ToArray(), "Редактирование аниме"))
            {
                resultAmv.Anm[lbAnm.SelectedIndex] = (string)frmEditItem.Value;
                ReFillAnime();
            }
        }

        private void mBtnAnmDel_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Действительно удалить запись?", "Удаление записи", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                resultAmv.Anm.RemoveAt(lbAnm.SelectedIndex);
                ReFillAnime();
            }
        }

        private void mBtnAwdAdd_Click(object sender, EventArgs e)
        {

            if (frmEditItem.ShowDialog("", resultAmv.Awd.ToArray(), Gl.DB.GetAllAwards().ToArray(), "Добавление аниме"))
            {
                resultAmv.Awd.Add((string)frmEditItem.Value);
                lbAwd.Add((string)frmEditItem.Value);
                lbAwd.SelectedIndex = lbAwd.Count - 1;
            }
        }

        private void mBtnAwdEdit_Click(object sender, EventArgs e)
        {
            List<String> ex = new List<string>(resultAmv.Awd);
            if (frmEditItem.ShowDialog(resultAmv.Awd[lbAwd.SelectedIndex], ex.ToArray(), Gl.DB.GetAllAwards().ToArray(), "Редактирование аниме"))
            {
                resultAmv.Awd[lbAwd.SelectedIndex] = (string)frmEditItem.Value;
                ReFillAwards();
            }
        }

        private void mBtnAwdDel_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Действительно удалить запись?", "Удаление записи", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                resultAmv.Awd.RemoveAt(lbAwd.SelectedIndex);
                ReFillAwards();
            }
        }

        #endregion *** события кнопок меню ************************************

        #region *** события листов ************************************

        private void lbTag_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (lbTag.SelectedIndex == -1) mBtnTagAdd_Click(null, null);
            else mBtnTagEdit_Click(null, null);
        }

        private void lbMsc_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (lbMsc.SelectedIndex == -1) mBtnMscAdd_Click(null, null);
            else mBtnMscEdit_Click(null, null);
        }

        private void lbAtr_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (lbAtr.SelectedIndex == -1) mBtnAtrAdd_Click(null, null);
            else mBtnAtrEdit_Click(null, null);
        }

        private void lbAnm_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (lbAnm.SelectedIndex == -1) mBtnAnmAdd_Click(null, null);
            else mBtnAnmEdit_Click(null, null);
        }

        private void lbAwd_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (lbAwd.SelectedIndex == -1) mBtnAwdAdd_Click(null, null);
            else mBtnAwdEdit_Click(null, null);
        }

        private void lbTag_MoveItem(object Sender, int oldInd, int newInd)
        {
            String c = resultAmv.Tags[oldInd];
            resultAmv.Tags.RemoveAt(oldInd);
            resultAmv.Tags.Insert(newInd, c);
        }

        private void lbMsc_MoveItem(object Sender, int oldInd, int newInd)
        {
            Music c = resultAmv.Msc[oldInd];
            resultAmv.Msc.RemoveAt(oldInd);
            resultAmv.Msc.Insert(newInd, c);
        }

        private void lbAtr_MoveItem(object Sender, int oldInd, int newInd)
        {
            String c = resultAmv.Atr[oldInd];
            resultAmv.Atr.RemoveAt(oldInd);
            resultAmv.Atr.Insert(newInd, c);
        }

        private void lbAnm_MoveItem(object Sender, int oldInd, int newInd)
        {
            String c = resultAmv.Anm[oldInd];
            resultAmv.Anm.RemoveAt(oldInd);
            resultAmv.Anm.Insert(newInd, c);
        }

        private void lbAwd_MoveItem(object Sender, int oldInd, int newInd)
        {
            string c = resultAmv.Awd[oldInd];
            resultAmv.Awd.RemoveAt(oldInd);
            resultAmv.Awd.Insert(newInd, c);
        }

        #endregion *** события листов ************************************

        #region *** события открытия меню ************************************

        private void menuMsc_Opening(object sender, CancelEventArgs e)
        {
            if (lbMsc.SelectedIndex == -1)
            {
                mBtnMscEdit.Visible = false;
                mBtnMscDel.Visible = false;
            }
            else
            {
                mBtnMscEdit.Visible = true;
                mBtnMscDel.Visible = true;
            }
        }

        private void menuAtr_Opening(object sender, CancelEventArgs e)
        {
            if (lbAtr.SelectedIndex == -1)
            {
                mBtnAtrEdit.Visible = false;
                mBtnAtrDel.Visible = false;
            }
            else
            {
                mBtnAtrEdit.Visible = true;
                mBtnAtrDel.Visible = true;
            }
        }

        private void menuAnm_Opening(object sender, CancelEventArgs e)
        {
            if (lbAnm.SelectedIndex == -1)
            {
                mBtnAnmEdit.Visible = false;
                mBtnAnmDel.Visible = false;
            }
            else
            {
                mBtnAnmEdit.Visible = true;
                mBtnAnmDel.Visible = true;
            }
        }

        private void menuAwd_Opening(object sender, CancelEventArgs e)
        {
            if (lbAwd.SelectedIndex == -1)
            {
                mBtnAwdEdit.Visible = false;
                mBtnAwdDel.Visible = false;
            }
            else
            {
                mBtnAwdEdit.Visible = true;
                mBtnAwdDel.Visible = true;
            }
        }

        private void menuTag_Opening(object sender, CancelEventArgs e)
        {
            if (lbTag.SelectedIndex == -1)
            {
                mBtnTagEdit.Visible = false;
                mBtnTagDel.Visible = false;
            }
            else
            {
                mBtnTagEdit.Visible = true;
                mBtnTagDel.Visible = true;
            }
        }

        #endregion *** события открытия меню ************************************

        #region *** AMVInfo *********************************************************************

        private void lvInfo_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (SelAmvInfo == null) return;
            AMVInfo ainf = SelAmvInfo;

            Gl.OpenAmv(editAmv);

            if (ainf.Site == SITE.AMVNews) Gl.OpenOnAMVNews(ainf.Number);
            if (ainf.Site == SITE.Akross) Gl.OpenOnAkross(ainf.Number);
            if (ainf.Site == SITE.CreaCon) Gl.OpenOnCreaCon(ainf.Number);
        }

        private void btnShowAmvInfoDB_Click(object sender, EventArgs e)
        {
            if (Width != 1488)
            {
                Width = 1488;
                btnShowAmvInfoDB.Text = "<<";
                Gl.frmEditAmv_bOpenFind = true;
            }
            else
            {
                Width = 576;
                btnShowAmvInfoDB.Text = ">>";
                Gl.frmEditAmv_bOpenFind = false;
            }
        }

        AMVInfo SelAmvInfo { get { return lvInfo.SelectedIndices.Count == 0 ? null : (AMVInfo)ShowList[lvInfo.SelectedIndices[0]].Tag; } }

        private void lvInfo_SelectedIndexChanged(object sender, EventArgs e)
        {
            btnBind.Enabled = false;
            grAmvInfo.BackColor = SystemColors.ControlLight;

            FillAmvInfoData(SelAmvInfo, false);

            if (SelAmvInfo != null)
            {
                btnBind.Enabled = !SelAmvInfo.IsBind;
                grAmvInfo.BackColor = SelAmvInfo.IsBind ? SystemColors.ControlDark : SystemColors.ControlLight;
            }
        }

        void FillAmvInfoData(AMVInfo ainf, bool InEditData)
        {
            if (InEditData)
            {
                if (ainf == null) return;

                resultAmv.Awd.Clear();
                resultAmv.Atr.Clear();
                resultAmv.Anm.Clear();
                resultAmv.Msc.Clear();

                resultAmv.Name = ainf.Name;
                resultAmv.Sites.Add(SITE.AMVNews, new AMVSite(ainf.Number, ainf.Rating, ainf.GrabDate));
                resultAmv.Comment = ainf.Comment;
                foreach (string str in ainf.TagGenre) if (!resultAmv.Tags.Contains(str)) resultAmv.Tags.Add(str);
                foreach (string str in ainf.TagOther) if (!resultAmv.Tags.Contains(str)) resultAmv.Tags.Add(str);
                foreach (string str in ainf.Anm) if (!resultAmv.Anm.Contains(str)) resultAmv.Anm.Add(str);
                foreach (string str in ainf.Msc)
                {
                    string[] sl = str.Split(new char[1] { '-' }, 2);
                    sl[0] = sl[0].Trim();
                    if (sl.Length == 2)
                    {
                        sl[1] = sl[1].Trim();
                        bool bExist = false;
                        foreach (Music music in resultAmv.Msc) if (music.Author == sl[0] && music.Name == sl[1]) { bExist = true; break; }
                        if (!bExist)
                        {
                            resultAmv.Msc.Add(new Music(sl[0], sl[1]));
                        }
                    }
                    else
                    {
                        if (frmEditMsc.ShowDialogAdd("", sl[0], resultAmv.Msc.ToArray()))
                        {
                            resultAmv.Msc.Add(frmEditMsc.val);
                        }
                    }
                }
                foreach (string str in ainf.Awd) if (!resultAmv.Awd.Contains(str)) resultAmv.Awd.Add(str);
                foreach (string str in ainf.Atr) if (!resultAmv.Atr.Contains(str)) resultAmv.Atr.Add(str);

                txbName.Text = resultAmv.Name;
                txbFPath.Text = resultAmv.FLocalPath;
                txbComment.Text = resultAmv.Comment;
                ReFillMusic();
                ReFillAuthors();
                ReFillAwards();
                ReFillAnime();
                ReFillTags();

                FillSitesInfo();

                txbMD5Len.Text = resultAmv.MD5Len;

            }
            else
            {
                txbInfoName.Text = "";
                txbInfoComments.Text = "";
                //lbInfoTags.Items.Clear();
                lbInfoAnime.Items.Clear();
                lbInfoAuthors.Items.Clear();
                lbInfoAwards.Items.Clear();
                lbInfoMusic.Items.Clear();

                if (ainf == null) return;

                txbInfoName.Text = ainf.Name;
                txbInfoComments.Text = ainf.Comment;
                foreach (string s in ainf.TagGenre) lbInfoTags.Items.Add(s);
                foreach (string s in ainf.TagOther) lbInfoTags.Items.Add(s);
                foreach (string s in ainf.Awd) lbInfoAwards.Items.Add(s);
                foreach (string s in ainf.Anm) lbInfoAnime.Items.Add(s);
                foreach (string s in ainf.Atr) lbInfoAuthors.Items.Add(s);
                foreach (string s in ainf.Msc) lbInfoMusic.Items.Add(s);
            }
        }

        void FillSitesInfo()
        {
            txbAmvNewsNum.Text = "";
            txbAkrossNum.Text = "";
            txbCreaConNum.Text = "";
            txbAmvNewsRating.Text = "";
            txbAkrossRating.Text = "";
            txbCreaConRating.Text = "";
            txbAmvNewsRatingDate.Text = "";
            txbAkrossRatingDate.Text = "";
            txbCreaConRatingDate.Text = "";

            if (resultAmv.Sites.ContainsKey(SITE.AMVNews))
            {
                txbAmvNewsNum.Text = resultAmv.Sites[SITE.AMVNews].ID.ToString();
                txbAmvNewsRating.Text = resultAmv.Sites[SITE.AMVNews].Rating == 0 ? "" : resultAmv.Sites[SITE.AMVNews].Rating.ToString();
                txbAmvNewsRatingDate.Text = resultAmv.Sites[SITE.AMVNews].Rating == 0 ? "" : resultAmv.Sites[SITE.AMVNews].LastUpdateRating.ToString("dd.MM.yyyy HH:mm:ss");
            }
            if (resultAmv.Sites.ContainsKey(SITE.Akross))
            {
                txbAkrossNum.Text = resultAmv.Sites[SITE.Akross].ID.ToString();
                txbAkrossRating.Text = resultAmv.Sites[SITE.Akross].Rating == 0 ? "" : resultAmv.Sites[SITE.Akross].Rating.ToString();
                txbAkrossRatingDate.Text = resultAmv.Sites[SITE.Akross].Rating == 0 ? "" : resultAmv.Sites[SITE.Akross].LastUpdateRating.ToString("dd.MM.yyyy HH:mm:ss");
            }
            if (resultAmv.Sites.ContainsKey(SITE.CreaCon))
            {
                txbCreaConNum.Text = resultAmv.Sites[SITE.CreaCon].ID.ToString();
                txbCreaConRating.Text = resultAmv.Sites[SITE.CreaCon].Rating == 0 ? "" : resultAmv.Sites[SITE.CreaCon].Rating.ToString();
                txbCreaConRatingDate.Text = resultAmv.Sites[SITE.CreaCon].Rating == 0 ? "" : resultAmv.Sites[SITE.CreaCon].LastUpdateRating.ToString("dd.MM.yyyy HH:mm:ss");
            }
        }

        // заполнение данныех по совпадению для аниме
        void FillFindData(string fName)
        {
            // проверка на номер в имени
            int AMVNewsNum = -1;
            string[] ssl = fName.Split('.');
            if (ssl.Length > 1)
            {
                if (ssl[0].Length == 5)
                {
                    if (int.TryParse(ssl[0].Substring(ssl[0].Length - 5, 5), out AMVNewsNum))
                    {
                        fName = fName.Replace(AMVNewsNum.ToString() + ".", "");
                    }
                    else AMVNewsNum = -1;
                }
            }
            fName = fName.ToUpper();

            // разбиваем имя файла на лексемы
            List<string> sl2 = AMVInfo.SplitTextForFind(fName.Replace("AMVNEWS.RU", ""));
            //List<string> sl1 = AMVInfo.SplitTextForFind(a.Name);

            foreach (AMVInfo ainf in Gl.infoL)
            {
                ainf.c_conformity = 0;
                ainf.c_Anm = 0;
                ainf.c_Atr = 0;
                ainf.c_Msc = 0;
                ainf.c_Name = 0;

                // если найден номер для AMVNews
                if (AMVNewsNum == ainf.Number && ainf.Site == SITE.AMVNews)
                {
                    ainf.c_conformity = 100;
                    continue;
                }

                // процент совпадения всех слов и коротких и длинных.
                // схожесть автора добавляет максимально 50%
                // схожесть музыки добавляет максимально 50%
                // схожесть аниме добавляет максимально 50%

                // сравнение
                double prcAtr = 0;
                double prcMsc = 0;
                double prcAnm = 0;
                double prcName = GetPercentCompare(sl2, ainf.slName);
                double prc = prcName;
                double k = 3.0; if (prc == 0) k = 2.0; else if (prc < 20) k = 2.5;
                if (ainf.slAtr.Count > 0)
                {
                    for (int m = 0; m < ainf.slAtr.Count; m++)
                        prcAtr += GetPercentCompare(sl2, ainf.slAtr[m]);
                    prcAtr /= (double)ainf.slAtr.Count;
                    prc += prcAtr / k;
                }
                if (ainf.slAnm.Count > 0)
                {
                    for (int m = 0; m < ainf.slAnm.Count; m++)
                        prcAnm += GetPercentCompare(sl2, ainf.slAnm[m]);
                    prcAnm /= (double)ainf.slAnm.Count;
                    prc += prcAnm / k;
                }
                if (ainf.slMsc.Count > 0)
                {
                    for (int m = 0; m < ainf.slMsc.Count; m++)
                        prcMsc += GetPercentCompare(sl2, ainf.slMsc[m]);
                    prcMsc /= (double)ainf.slMsc.Count;
                    prc += prcMsc / k;
                }

                if (prc > 10)
                {
                    if (prc > 99) prc = 99;

                    ainf.c_conformity = prc;
                    ainf.c_Anm = prcAnm;
                    ainf.c_Atr = prcAtr;
                    ainf.c_Msc = prcMsc;
                    ainf.c_Name = prcName;
                }
            }
            AMVInfo.SortMode = AMVInfo.SortMODE.C_CONFORMITY;
            AMVInfo.SortDesc = true;
            Gl.infoL.Sort();
        }

        // заполнение привязок
        void FillBindData()
        {
            foreach (AMVInfo ainf in Gl.infoL)
            {
                ainf.IsBind = false;
                for (int i = 0; i < Gl.DB.Count; i++)
                {
                    if (Gl.DB[i].Sites.ContainsKey(ainf.Site) && Gl.DB[i].Sites[ainf.Site].ID == ainf.Number)
                    {
                        ainf.IsBind = true;
                        break;
                    }
                }
            }
        }

        void FillCashList()
        {
            CashList.Clear();
            foreach (AMVInfo ainf in Gl.infoL)
            {
                CashList.Add(GetItmInfo(ainf));
            }
        }

        double GetPercentCompare(List<string> slMain, List<string> slCmp)
        {
            return GetPercentCompare(slMain, slCmp, false);
        }

        double GetPercentCompare(List<string> slMain, List<string> slCmp, bool deleteFindWordsFromSlMain)
        {
            double len = slMain.Count;
            if (slCmp.Count > slMain.Count) len = slCmp.Count;
            int cntCmp = 0;
            for (int i = 0; i < slCmp.Count; i++)
                for (int j = 0; j < slMain.Count; j++)
                    if (slCmp[i] == slMain[j])
                    {
                        cntCmp++;
                        if (deleteFindWordsFromSlMain) slMain.RemoveAt(j);
                        break;
                    }
            return (cntCmp / len) * 100.0;
        }

        List<ListViewItem> CashList = new List<ListViewItem>();
        List<ListViewItem> ShowList = new List<ListViewItem>();

        private void lvInfo_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
        {
            e.Item = ShowList[e.ItemIndex];
        }

        private void lvInfo_VirtualItemsSelectionRangeChanged(object sender, ListViewVirtualItemsSelectionRangeChangedEventArgs e)
        {
            //
        }

        void ReFillAmvInfoList()
        {
            // для разового обновления
            List<ListViewItem> tmpShowList = new List<ListViewItem>();

            lvInfo.Items.Clear();
            for (int i = 0; i < Gl.infoL.Count; i++)
            {
                if (RecInFlt(Gl.infoL[i]))
                {
                    tmpShowList.Add(CashList[i]);
                }
            }

            lvInfo.VirtualListSize = tmpShowList.Count;
            ShowList = tmpShowList;
            lblLen.Text = ShowList.Count.ToString() + "\\" + CashList.Count.ToString();

            lvInfo.Refresh();
        }

        bool RecInFlt(AMVInfo ainf)
        {
            if (txbFltAll.Text.Trim() != "")
            {
                string str = txbFltAll.Text.Trim().ToUpper();

                bool bFind = false;

                if (ainf.Name.ToUpper().Contains(str)) bFind = true;
                if (ainf.Number.ToString().Contains(str)) bFind = true;
                if (ainf.Comment.ToUpper().Contains(str)) bFind = true;

                foreach (string s in ainf.Anm) if (s.ToUpper().Contains(str)) { bFind = true; break; }
                foreach (string s in ainf.Atr) if (s.ToUpper().Contains(str)) { bFind = true; break; }
                foreach (string s in ainf.Atr) if (s.ToUpper().Contains(str)) { bFind = true; break; }
                foreach (string s in ainf.Awd) if (s.ToUpper().Contains(str)) { bFind = true; break; }
                foreach (string s in ainf.Msc) if (s.ToUpper().Contains(str)) { bFind = true; break; }
                foreach (string s in ainf.TagGenre) if (s.ToUpper().Contains(str)) { bFind = true; break; }
                foreach (string s in ainf.TagOther) if (s.ToUpper().Contains(str)) { bFind = true; break; }

                if (!bFind) return false;
            }

            if (chbxHideBind.Checked && ainf.IsBind) return false;

            if (txbFltName.Text.Trim() != "")
            {
                if (!ainf.Name.ToUpper().Contains(txbFltName.Text.Trim().ToUpper())) return false;
            }

            if (txbFltAnm.Text.Trim() != "")
            {
                string str = txbFltAnm.Text.Trim().ToUpper();
                bool bFind = false;
                foreach (string s in ainf.Anm) if (s.ToUpper().Contains(str)) { bFind = true; break; }
                if (!bFind) return false;
            }

            if (txbFltAtr.Text.Trim() != "")
            {
                string str = txbFltAtr.Text.Trim().ToUpper();
                bool bFind = false;
                foreach (string s in ainf.Atr) if (s.ToUpper().Contains(str)) { bFind = true; break; }
                if (!bFind) return false;
            }

            if (txbFltAwd.Text.Trim() != "")
            {
                string str = txbFltAwd.Text.Trim().ToUpper();
                bool bFind = false;
                foreach (string s in ainf.Awd) if (s.ToUpper().Contains(str)) { bFind = true; break; }
                if (!bFind) return false;
            }

            if (txbFltMsc.Text.Trim() != "")
            {
                string str = txbFltMsc.Text.Trim().ToUpper();
                bool bFind = false;
                foreach (string s in ainf.Msc) if (s.ToUpper().Contains(str)) { bFind = true; break; }
                if (!bFind) return false;
            }

            if (txbFltTags.Text.Trim() != "")
            {
                string str = txbFltTags.Text.Trim().ToUpper();
                bool bFind = false;
                foreach (string s in ainf.TagGenre) if (s.ToUpper().Contains(str)) { bFind = true; break; }
                if (!bFind) foreach (string s in ainf.TagOther) if (s.ToUpper().Contains(str)) { bFind = true; break; }
                if (!bFind) return false;
            }

            return true;
        }

        ListViewItem GetItmInfo(AMVInfo a)
        {
            StringBuilder s = new StringBuilder();

            s.Append(a.c_conformity.ToString("00"));
            s.Append("% (N:");
            s.Append(a.c_Name.ToString("00"));
            s.Append("% An:");
            s.Append(a.c_Anm.ToString("00"));
            s.Append("% At:");
            s.Append(a.c_Atr.ToString("00"));
            s.Append("% M:");
            s.Append(a.c_Msc.ToString("00"));
            s.Append("%)");

            ListViewItem ret = new ListViewItem(s.ToString());

            ret.SubItems.Add(a.Number.ToString("00000") + " [" + a.Site.ToString() + "] ");
            ret.SubItems.Add(a.Name);
            ret.SubItems.Add(a.Atr[0]);
            if (a.Msc.Count > 0) ret.SubItems.Add(a.Msc[0]); else ret.SubItems.Add("");
            if (a.Anm.Count > 0) ret.SubItems.Add(a.Anm[0]); else ret.SubItems.Add("");

            ret.Tag = a;

            if (a.IsBind) ret.ForeColor = Color.Gray;

            return ret;
        }

        private void lbInfoTags_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (lbInfoTags.SelectedIndex == -1) return;
            if (!resultAmv.Tags.Contains(lbInfoTags.SelectedItem.ToString()))
            {
                resultAmv.Tags.Add(lbInfoTags.SelectedItem.ToString());
                ReFillTags();
            }
            lbInfoTags.Items.RemoveAt(lbInfoTags.SelectedIndex);
        }

        private void lbInfoMusic_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (lbInfoMusic.SelectedIndex == -1) return;
            string[] sl = lbInfoMusic.SelectedItem.ToString().Split(new char[1] { '-' }, 2);
            sl[0] = sl[0].Trim();
            if (sl.Length == 2)
            {
                sl[1] = sl[1].Trim();
                bool bExist = false;
                foreach (Music music in resultAmv.Msc) if (music.Author == sl[0] && music.Name == sl[1]) { bExist = true; break; }
                if (!bExist)
                {
                    resultAmv.Msc.Add(new Music(sl[0], sl[1]));
                    ReFillMusic();
                }
                lbInfoMusic.Items.RemoveAt(lbInfoMusic.SelectedIndex);
            }
            else
            {
                if (frmEditMsc.ShowDialogAdd("", sl[0], resultAmv.Msc.ToArray()))
                {
                    resultAmv.Msc.Add(frmEditMsc.val);
                    ReFillMusic();
                    lbInfoMusic.Items.RemoveAt(lbInfoMusic.SelectedIndex);
                }
            }
        }

        private void lbInfoAuthors_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (lbInfoAuthors.SelectedIndex == -1) return;
            if (!resultAmv.Atr.Contains(lbInfoAuthors.SelectedItem.ToString()))
            {
                resultAmv.Atr.Add(lbInfoAuthors.SelectedItem.ToString());
                ReFillAuthors();
            }
            lbInfoAuthors.Items.RemoveAt(lbInfoAuthors.SelectedIndex);
        }

        private void lbInfoAnime_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (lbInfoAnime.SelectedIndex == -1) return;
            if (!resultAmv.Anm.Contains(lbInfoAnime.SelectedItem.ToString()))
            {
                resultAmv.Anm.Add(lbInfoAnime.SelectedItem.ToString());
                ReFillAnime();
            }
            lbInfoAnime.Items.RemoveAt(lbInfoAnime.SelectedIndex);
        }

        private void lbInfoAwards_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (lbInfoAwards.SelectedIndex == -1) return;
            if (!resultAmv.Awd.Contains(lbInfoAwards.SelectedItem.ToString()))
            {
                resultAmv.Awd.Add(lbInfoAwards.SelectedItem.ToString());
                ReFillAwards();
            }
            lbInfoAwards.Items.RemoveAt(lbInfoAwards.SelectedIndex);
        }

        private void txbInfoComments_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            txbComment.AppendText((txbComment.Text.Trim() == "" ? "" : "\r\n") + txbInfoComments.Text);
            txbInfoComments.Text = "";
        }

        private void txbInfoName_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            txbName.Text = txbInfoName.Text;
            txbInfoName.Text = "";
        }

        private void btnInfoCopyAll_Click(object sender, EventArgs e)
        {
            txbInfoName_MouseDoubleClick(null, null);
            txbInfoComments_MouseDoubleClick(null, null);
            while (lbInfoTags.Items.Count > 0) { lbInfoTags.SelectedIndex = 0; lbInfoTags_MouseDoubleClick(null, null); }
            while (lbInfoMusic.Items.Count > 0) { lbInfoMusic.SelectedIndex = 0; lbInfoMusic_MouseDoubleClick(null, null); }
            while (lbInfoAuthors.Items.Count > 0) { lbInfoAuthors.SelectedIndex = 0; lbInfoAuthors_MouseDoubleClick(null, null); }
            while (lbInfoAnime.Items.Count > 0) { lbInfoAnime.SelectedIndex = 0; lbInfoAnime_MouseDoubleClick(null, null); }
            while (lbInfoAwards.Items.Count > 0) { lbInfoAwards.SelectedIndex = 0; lbInfoAwards_MouseDoubleClick(null, null); }
        }

        private void btnBind_Click(object sender, EventArgs e)
        {
            AMVInfo ainf = SelAmvInfo;
            if (ainf.Site == SITE.AMVNews)
            {
                txbAmvNewsNum.Text = ainf.Number.ToString();
                txbAmvNewsRating.Text = ainf.Rating.ToString();
                txbAmvNewsRatingDate.Text = ainf.GrabDate.ToString("dd.MM.yyyy HH:mm:ss");
            }
            if (ainf.Site == SITE.Akross)
            {
                txbAkrossNum.Text = ainf.Number.ToString();
                txbAkrossRating.Text = ainf.Rating.ToString();
                txbAkrossRatingDate.Text = ainf.GrabDate.ToString("dd.MM.yyyy HH:mm:ss");
            }
            if (ainf.Site == SITE.CreaCon)
            {
                txbCreaConNum.Text = ainf.Number.ToString();
                txbCreaConRating.Text = ainf.Rating.ToString();
                txbCreaConRatingDate.Text = ainf.GrabDate.ToString("dd.MM.yyyy HH:mm:ss");
            }
            btnBind.Enabled = false;
        }

        private void txbFlt_TextChanged(object sender, EventArgs e)
        {
            ReFillAmvInfoList();
        }

        private void btnCleaFlt_Click(object sender, EventArgs e)
        {
            txbFltAll.Clear();
            txbFltAnm.Clear();
            txbFltAtr.Clear();
            txbFltAwd.Clear();
            txbFltMsc.Clear();
            txbFltTags.Clear();
        }

        #endregion *** AMVInfo *********************************************************************

        private void FormEditAmv_Move(object sender, EventArgs e)
        {
            Gl.frmEditAmv_bOpenFind = Width == 1488;
            Gl.frmEditAmv_Pos = Location;
        }

        private void lvInfo_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.P) Gl.OpenAmv(editAmv);
        }

        private void btnShowPageAMVNews_Click(object sender, EventArgs e)
        {
            int num = 0;
            if (!int.TryParse(txbAmvNewsNum.Text.Trim(), out num))
            {
                MessageBox.Show("Идентификатор AMVNews имеет некорректный формат или пуст.");
                return;
            }
            Gl.OpenOnAMVNews(Convert.ToInt32(txbAmvNewsNum.Text.Trim()));
        }

    }
}
